package com.remote.ui.event;


import com.remote.common.command.Commands;
import com.remote.common.model.ClientInfo;
import com.remote.common.model.fx.MasterMouseEvent;
import com.remote.common.util.TaskExecutors;
import com.remote.ui.constant.UIConstant;
import com.remote.ui.core.Controller;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Cool-Coding
 * 2018/7/26
 */
public class MouseHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(MouseHandler.class);


    private Controller controller;

    /**
     * 记录点击次数
     */
    private AtomicInteger clickNum = new AtomicInteger(0);

    /**
     * 是否已经
     */
    private volatile boolean isDoubleClicked;

    /**
     * 记录上次单击的鼠标键位
     */
    private MouseButton preButton = null;


    public MouseHandler(Controller controller) {
        this.controller = controller;
    }

    public void mouseClicked(MouseEvent e) {
        //每次单击都将此标识示false，防止双击后的单击被认为是双击
        isDoubleClicked = false;
        //点击数加1如果等于2，说明单击了两次,并且两次单击了相同的键，则是双击
        if (clickNum.incrementAndGet() == 2 && isTheSameButton(e)) {
            isDoubleClicked = true;
            preButton = null;
            this.mouseDoubleClicked(e);
            return;
        }
        //定义定时器
        TaskExecutors.submit(() -> {
            if (isDoubleClicked) {//如果双击事件已经执行,那么直接取消单击执行
                clickNum.set(0);
                isDoubleClicked = false;
                return;
            }
            if (clickNum.getAndDecrement() == 1) {//定时器等待0.2秒后,双击事件仍未发生,执行单击事件
                preButton = null;
                mouseSingleClicked(e);
            }
        }, 500);
        preButton = e.getButton();
    }

    //此次单击的键与上次是否为同一个键
    private boolean isTheSameButton(MouseEvent e) {
        return preButton != null && e.getButton() == preButton;
    }


    public void mouseDragged(MouseEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        mouseEvent.dragged(e, (int) e.getX(), (int) e.getY());
        sendMosueEvent(mouseEvent);
    }


    public void mousePressed(MouseEvent e) {
            /*final MasterMouseEvent mouseEvent = new MasterMouseEvent();
            mouseEvent.mousePressed(e.getButton());
            sendMosueEvent(mouseEvent);*/
    }


    public void mouseMoved(MouseEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        mouseEvent.mouseMoved((int) e.getX(), (int) e.getY());
        sendMosueEvent(mouseEvent);
    }

    /**
     * 鼠标单击事件
     *
     * @param e 事件源参数
     */
    public void mouseSingleClicked(MouseEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        mouseEvent.buttonClicked(e, (int) e.getX(), (int) e.getY());
        sendMosueEvent(mouseEvent);
    }

    /**
     * 鼠标双击事件
     *
     * @param e 事件源参数
     */
    private void mouseDoubleClicked(MouseEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        mouseEvent.buttonDoubleClick(e, (int) e.getX(), (int) e.getY());
        sendMosueEvent(mouseEvent);
    }


    public void mouseReleased(MouseEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        mouseEvent.mouseReleased(e);
        sendMosueEvent(mouseEvent);
    }

    public void mouseWheelMoved(ScrollEvent e) {
        final MasterMouseEvent mouseEvent = new MasterMouseEvent();
        int count = (int) e.getDeltaX();
        mouseEvent.mouseWheel(count);
        sendMosueEvent(mouseEvent);
    }

    private void sendMosueEvent(MasterMouseEvent mouseEvent) {
        try {
            ClientInfo clientInfo = (ClientInfo) controller.getValue(UIConstant.P_CLIENT_INFO);
            controller.getControllerManager().getCommandContext().fireCommand(clientInfo.getClientId(), Commands.MOUSE, mouseEvent);
        } catch (Exception e) {
            controller.showMessage("异常", e.getMessage());
        }
    }


}
